/*
 * Galaxium Messenger
 * Copyright (C) 2008 Jensen Somers <jensen.somers@gmail.com>
 * 
 * License: GNU General Public License (GPL)
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the Free
 * Software Foundation; either version 2 of the License, or (at your option)
 * any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;

using NDesk.DBus;
using org.freedesktop.DBus;

using Anculus.Core;
using Galaxium.Core;

namespace Galaxium.Client
{
	/// <summary>
	/// Song information backend used to obtain information from the bmpx
	/// media player.
	/// </summary>
	public sealed class BMPxSongInformationBackend : AbstractSongInformationBackend
	{
		private IBMPxPlayer player;
		private bool _dbus;
		
		[Interface ("org.freedesktop.MediaPlayer")]
		interface IBMPxPlayer
		{
			IDictionary<string, object> GetMetadata();
			
			event StatusChangeHandler StatusChange;
		}
		
		delegate void StatusChangeHandler(int status);
		
		public override void Initialize ()
		{
			try
			{
				BusG.Init ();
				_dbus = true;
			}
			catch
			{
			}
		}

		public override void Unload ()
		{
		}
		
		public override string Name
		{
			get { return "BMPx"; }
		}
		
		public override bool RequiresPolling
		{
			get { return false; }
		}
		
		public override bool IsAvailable()
		{
			if (!_dbus)
				return false;
			
			try
			{
				if (player != null)
					player.StatusChange -= EmitSongChanged;
				
				player = FindBMPxInstance();
				if (player != null)
					player.StatusChange += EmitSongChanged;
			}
			catch
			{
				return false;
			}
			
			if (player == null)
				return false;
			
			EmitSongChanged(1);
			return true;				
		}
		
		public override SongInformation GetCurrentSong ()
		{
			try
			{
				IDictionary<string, object> dict = player.GetMetadata();
				
				string title = null;
				string artist = null;
				string album = null;
				int duration = 0;
				
				if (dict.ContainsKey("title"))
					title = dict["title"].ToString();
				
				if (dict.ContainsKey("artist"))
					artist = dict["artist"].ToString();
				
				if (dict.ContainsKey("album"))
					album = dict["album"].ToString();
				
				if (dict.ContainsKey("time"))
					duration = Convert.ToInt32(dict["time"].ToString());
				
				SongInformation info = new SongInformation(artist, title, album, duration);
				return info;
			}
			catch
			{
				return null;
			}
		}
		
		private void EmitSongChanged(int changed)
		{
			if (changed == 1)
			{
				SongInformation info = GetCurrentSong();
				OnSongChanged(new SongInformationEventArgs(info));
			}				
		}
		
		private IBMPxPlayer FindBMPxInstance()
		{
			if (!Bus.Session.NameHasOwner("org.mpris.bmp"))
				return null;
			
			return Bus.Session.GetObject<IBMPxPlayer>("org.mpris.bmp", new ObjectPath ("/Player"));
		}
	}
}